const Type Parameters
こういう関数に対し、引数を渡すときに
code:ts
type HasNames = { names: readonly string[] };
function getNamesExactly<T extends HasNames>(arg: T): T"names" { return arg.names;
}
as constを付けないと型情報が落ちてしまう
code:ts
// Inferred type: string[]
code:ts
利用者側がいちいち気をつけないといけない
const Type Parametersを使って関数定義側を変更すると自動で強くできる
code:ts
type HasNames = { names: readonly string[] };
function getNamesExactly<const T extends HasNames>(arg: T): T"names" { // ^^^^^
return arg.names;
}
code:ts
ちなみにこのconstのキーワードは、関数やmethodの型引数にしか使えない
なので、以下のようには書けない
code:ts
type Props<const T> = {..}
もちろん、関数型には書ける
code:ts
type Fn<const T> = (..) => ..
ただし、関数を呼び出す際に、引数部分に直接値が書かれた場合にのみ有効
変数定義を介すると効かない
なので、以下のように書いても緩いまま
code:ts
type HasNames = { names: readonly string[] };
function getNamesExactly<const T extends HasNames>(arg: T): T'names' { return arg.names;
}
// Inferred type: string[]
const names2 = getNamesExactly({ names });
でもまあこれは、関数を定義する側からしたら知ったこっちゃないので、constを付けるようにしておけば良いmrsekut.icon
recordに対して使う例
code:ts
type HasNames = { names: string };
function getNamesExactly<const T extends HasNames>(arg: T): T'names' { return arg.names;
}
getNamesExactly({ names: 'a' });
パッと思いつくユースケースとだと、Next.jsのRouteの定義とかかmrsekut.icon
Next.js内部の話なので触れないが。
code:ts
export type Route<const T extends string = string> =
__next_route_internal_types__.RouteImpl<T>
以下のように書くことが多いので。
code:ts
<Link href={/posts/${postId} as const} />
使い所を探したいなら、as constでgrepして、適用するべきかどうか考えれば良いmrsekut.icon